package com.hazardousholdings.unkj.validation;

/**
 * RangeValidator validates that the input value falls within a given range. 
 * Input values as well as max and min values must implement Comparable.
 */
public class RangeValidator<T extends Comparable<? super T>> extends CompositeValidator<T> {
	
	/**
	 * Instantiates a new range validator.
	 * By default, min and max are inclusive.
	 * 
	 * @param min the minimum value of input
	 * @param max the maximum value of input
	 */
	public RangeValidator(T min, T max) {
		this(min, max, true, true);
	}
	
	/**
	 * Instantiates a new range validator.
	 * 
	 * @param min the minimum value of input
	 * @param max the maximum value of input
	 * @param includesMin if true, low is inclusive (>=)
	 * @param includesMax if true, high is inclusive (<=)
	 */
	public RangeValidator(T min, T max, boolean includesMin, boolean includesMax) {
		super(String.format("Input must be between %s (%s) and %s (%s)", 
				min, includesMin ? "inclusive" : "exclusive", 
				max, includesMax ? "inclusive" : "exclusive"));
		
		CompositeValidator<T> lowValidator = new CompositeValidator<T>();
		lowValidator.addValidator(new MinimumValidator<T>(min));
		if(!includesMin) {
			lowValidator.addValidator(new NotEqualValidator<T>(min));
		}
		this.addValidator(lowValidator);
		
		CompositeValidator<T> highValidator = new CompositeValidator<T>();
		highValidator.addValidator(new MaximumValidator<T>(max));
		if(!includesMax) {
			highValidator.addValidator(new NotEqualValidator<T>(max));
		}
		this.addValidator(highValidator);
	}

}
